﻿using System;
using System.Collections.Generic;
using SoulDoorEngine.Framework.Components;

namespace SoulDoorEngine.Framework.Screens
{
    /// <summary>
    /// 一个屏幕包含多个引擎组件，下层的屏幕先绘制
    /// </summary>
    public class Screen
    {
        private ComponentCollection _Components;
        private bool _Visible = true;
        private bool _BlockUpdate = false;
        private bool _OverrideUpdateBlocked = false;
        private bool _BlockDraw = false;
        private bool _OverrideDrawBlocked = false;
        private bool _BlockInput = false;
        private bool _OverrideInputBlocked = false;
        private bool _InputDisabled = false;
        private bool _IsInputAllowed = true;
        private string _Name;
        private bool _Initialized = false;

        public event EventHandler OnInitialized;

        /// <summary>
        /// 是否已被初始化
        /// </summary>
        public bool Initialized
        {
            get { return _Initialized; }
            set
            {
                _Initialized = value;
                if (OnInitialized != null)
                {
                    this.OnInitialized(this, new EventArgs());
                }
            }
        }

        /// <summary>
        /// 提供如Engine.Screens[Name]的索引服务
        /// </summary>
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        
        /// <summary>
        /// 引擎是否允许输入
        /// </summary>
        public bool IsInputAllowed
        {
            get { return _IsInputAllowed; }
            set { _IsInputAllowed = value; }
        }
        
        /// <summary>
        /// 用户是否允许输入，例如载入屏幕时的一些交互
        /// </summary>
        public bool InputDisabled
        {
            get { return _InputDisabled; }
            set { _InputDisabled = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool OverrideInputBlocked
        {
            get { return _OverrideInputBlocked; }
            set { _OverrideInputBlocked = value; }
        }

        /// <summary>
        /// 是否可阻止下层的屏幕输入，如暂停菜单
        /// </summary>
        public bool BlockInput
        {
            get { return _BlockInput; }
            set { _BlockInput = value; }
        }
        
        /// <summary>
        /// 是否可在上层屏幕被阻止时任然绘制，如背景画面
        /// </summary>
        public bool OverrideDrawBlocked
        {
            get { return _OverrideDrawBlocked; }
            set { _OverrideDrawBlocked = value; }
        }
        
        /// <summary>
        /// 是否可阻止下层的屏幕绘制，如暂停菜单
        /// </summary>
        public bool BlockDraw
        {
            get { return _BlockDraw; }
            set { _BlockDraw = value; }
        }
        
        /// <summary>
        /// 是否可在上层屏幕被阻止时任然更新，如背景画面
        /// </summary>
        public bool OverrideUpdateBlocked
        {
            get { return _OverrideUpdateBlocked; }
            set { _OverrideUpdateBlocked = value; }
        }
        
        /// <summary>
        /// 是否可阻止下层的屏幕更新，如暂停菜单
        /// </summary>
        public bool BlockUpdate
        {
            get { return _BlockUpdate; }
            set { _BlockUpdate = value; }
        }
        
        /// <summary>
        /// 是否可视
        /// </summary>
        public bool Visible
        {
            get { return _Visible; }
            set { _Visible = value; }
        }
        
        /// <summary>
        /// 组件集合
        /// </summary>
        public ComponentCollection Components
        {
            get { return _Components; }
            set { _Components = value; }
        }

        public Screen(string name)
        {
            this.Components = new ComponentCollection(this);
            this.Name = name;
            Engine.Screens.Add(this);
            if (!this.Initialized)
            {
                this.Initialize();
            }
        }

        /// <summary>
        /// 可重载以初始化屏幕
        /// </summary>
        public virtual void Initialize()
        {
            this.Initialized = true;
        }

        /// <summary>
        /// 更新该屏幕下所有可更新组件
        /// </summary>
        public virtual void Update()
        {
            List<Component> toUpdate = new List<Component>();

            foreach (Component item in this.Components)
            {
                toUpdate.Add(item);
            }

            foreach (Component item in toUpdate)
            {
                if (item.IsInitialized)
                {
                    item.Update();
                }
            }
        }

        /// <summary>
        /// 绘制该屏幕下所有可绘制组件
        /// </summary>
        /// <param name="predicate"></param>
        public virtual void Draw(ComponentPredicate predicate)
        {
            List<Component> toDraw = new List<Component>();

            //Ver.0.17修正：添加ListDrawOrder
            foreach (Component item in this.Components.ListDrawOrder)
            {
                if (predicate.IsComponentEligible(item))
                {
                    toDraw.Add(item);
                }
            }

            List<Component> list2D = new List<Component>();

            foreach (Component item in toDraw)
            {
                if (item.Visible && item.IsInitialized)
                {
                    if (item is I2DComponent)
                    {
                        list2D.Add(item);
                    }
                    else
                    {
                        item.Draw();
                    }
                }
            }

            //*******************************************************************
            //2011.12.17 SoulDoorEngine0.25.5.9x 打包后 重要更改（2D、3D组件绘制策略）
            //*******************************************************************
            Engine.SpriteBatch.Begin(Microsoft.Xna.Framework.Graphics.SpriteSortMode.BackToFront, Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend);
            foreach (Component item in list2D)
            {
                item.Draw();
            }
            Engine.SpriteBatch.End();
        }

        /// <summary>
        /// 禁用该屏幕
        /// </summary>
        public virtual void Disable()
        {
            this.Components.Clear();

            Engine.Screens.Remove(this);

            if (Engine.DefaultScreen == this)
            {
                Engine.DefaultScreen = Engine.BackgroundScreen;
            }
        }

        /// <summary>
        /// 重载Tostring
        /// </summary>
        /// <returns>返回Name属性</returns>
        public override string ToString()
        {
            return this.Name;
        }
    }
}
